/****************************************************
    RAToSO - Ricardito's Anti-Massacre Total System cOnfiguration
    Copyright (C) 2012  Ricardo Kehrle Miranda

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
        
-----------------------------------------------------
                   ___________
                 _|           |_
              __|     _____     |__
             |       |     |       |
             |  __    -----    __  |
             | |__|1         2|__| |
              |    __         __  |
               |  |__|4     5|__| |
                |_              _|
                  -------------- 
                  1- PPM
                  2- +5V
                  3- RX
                  4- TX
*****************************************************/

#include <TM1638.h>
#include <Servo.h> 

// initialize variables
int inByte;
byte keys;
int i;
const byte button = 1;
int count=0;
int servoPin = 13;
int servoPos = 90;

// set LM1638 module
TM1638 module(3, 2, 4);

// set servo
Servo myservo;

// servo function setup
void servoSetup(void) {
  myservo.attach(servoPin);  
  myservo.write(servoPos);
  module.setDisplayToDecNumber(servoPos,0);  
  for( i=0; i<8; i++){
    module.setLED(0, i);
  }
  blinkServos();
  module.setLED(TM1638_COLOR_RED, 0);
  module.setLED(TM1638_COLOR_RED, 1);
  module.setLED(TM1638_COLOR_RED, 2);
  module.setLED(TM1638_COLOR_GREEN, 4);
  module.setLED(TM1638_COLOR_RED, 6);
  module.setLED(TM1638_COLOR_RED, 7);
}

// radio function setup
void radioSetup(void) {
  module.setDisplayToDecNumber(servoPos,0);  
  for( i=0; i<8; i++){
    module.setLED(0, i);
  }
  blinkRadio();
  module.setLED(TM1638_COLOR_GREEN, 0);
  module.setLED(TM1638_COLOR_GREEN, 1);
  module.setLED(TM1638_COLOR_RED, 4);
  module.setLED(TM1638_COLOR_GREEN, 7);
}

// display strings
const char writing[] = "writing ";
const char kinetic[] = "KInETIC ";
const char bytes[] = "69 bytes";
const char done[] = "done.   ";
const char yesno[] = "yes   no";
const char sinao[] = "SIM  NAO";
const char leaving[] = "leauing ";
const char servos[] = "SERUOS  ";
const char radio[] = "radio   ";
const char blank[] = "        ";



// display functions
void blinkServos() {
  module.setDisplayToString(servos);
  delay(500);
  module.setDisplayToString(blank);
  delay(500);
  module.setDisplayToString(servos);
  delay(500);
  module.setDisplayToString(blank);
  delay(500);
  module.setDisplayToString(servos);
  delay(500);
  module.setDisplayToString(blank);
}

void blinkRadio() {
  module.setDisplayToString(radio);
  delay(500);
  module.setDisplayToString(blank);
  delay(500);
  module.setDisplayToString(radio);
  delay(500);
  module.setDisplayToString(blank);
  delay(500);
  module.setDisplayToString(radio);
  delay(500);
  module.setDisplayToString(blank);
}

// MENU
unsigned int confItem = 1;
unsigned int confSize = 4;
char* confMenu[] = { "TEST CFG", "CIneTIC ", "bIxLEr  ", "UGLyCuxo" }; 

// Configuration data               
byte confTeste[] = { 0xff, 0x55, 0xff, 0x10, 0x00,
0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x00, 0x00,
0x00, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64,
0x64, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x78, 0x00,
0x88, 0x00, 0x00, 0x00,
0x64, 0x64, 0x03, 0x00,
0x64, 0x64, 0x03, 0x00,
0x64, 0x64, 0x03, 0x00,
0x00, 0x00, 0x00, 0x0a,
0x79};
 
byte confKinetic[] = { 0xff, 0x55, 0xff, 0x10, 0x00,
0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x00, 0x00,
0x00, 0x32, 0x32, 0x78,
0x78, 0x78, 0x78, 0x64,
0x64, 0x64, 0x64, 0x64,
0x64, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0xd3, 0x00, 0xd8,
0x00, 0x00, 0x00, 0x00,
0x64, 0x64, 0x03, 0x00,
0x64, 0x64, 0x03, 0x00,
0x64, 0x64, 0x03, 0x00,
0x00, 0x00, 0x00, 0x0b,
0x10};

byte confBixler[] = {0xff, 0x55, 0xff, 0x10, 0x08,
0x64, 0x64, 0x64, 0x64, 
0x64, 0x64, 0x00, 0x00, 
0x00, 0x64, 0x64, 0x64,  
0x64, 0x78, 0x78, 0x64, 
0x64, 0x64, 0x64, 0x64,
0x64, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x88,
0x9c, 0x00, 0x00, 0x00,
0x64, 0x64, 0x03, 0x00,
0x64, 0x64, 0x03, 0x00,
0x64, 0x64, 0x03, 0x00,
0x00, 0x00, 0x00, 0x0a,
0xcd};

byte confUglycuxo[] = {0xff, 0x55, 0xff, 0x10, 0x0b,
0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x00, 0x00,
0x00, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64,
0x64, 0x64, 0x64, 0x64,
0x64, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x50, 0x88,
0x00, 0x00, 0x00, 0x00,
0x64, 0x64, 0x03, 0x00,
0x64, 0x64, 0x03, 0x00,
0x64, 0x64, 0x03, 0x00,
0x00, 0x00, 0x00, 0x0a,
0x5c};
                    
// send configuration function
void writeConfToSerial(int confItem) {
  switch( confItem ) {
   case 1:
    Serial.write(confTeste, 70);
   break;    
   case 2:
    Serial.write(confKinetic, 70);
   break;
   case 3:
    Serial.write(confBixler, 70);
   break;
   case 4:
    Serial.write(confUglycuxo, 70);
   break;
 }
}
                                
void setup() {
  // initialize both serial ports:
  Serial.begin(115000);
}

// initialize some variables and start main routine
boolean confirmDone, changeMenu;
void loop() {
  
  changeMenu=false;
  radioSetup();
 
  while(!changeMenu) {
    // read keys
    keys = module.getButtons();
    // check if button 5 was pressed
    if( keys == ( button << 4 ) ) {
      break;
    }
    
    // evaluate keys
    confirmDone = false;
    switch( keys ) {
     case (button << 1):
       confItem++;
       if (confItem > confSize) {
         confItem = 1;
       }
     break;
     case (button << 0):
       confItem--;
       if (confItem < 1) {
         confItem = confSize;
       }
     break;
     
     // confirm and send to serial pin
     case (button << 7):
       module.clearDisplay();
       module.setDisplayToString(yesno);
       module.setLED(0, 0);
       module.setLED(0, 7);
       module.setLED(0, 4);
       module.setLED(TM1638_COLOR_GREEN, 1);
       module.setLED(TM1638_COLOR_RED, 6);
       delay(250);
       while( !confirmDone ) {
         if ( module.getButtons() & 2 ) {     
           writeConfToSerial(confItem);
           module.setDisplayToString(done);
           delay(1000);
           confirmDone=true;
         }
         else if (module.getButtons() & 64 ) {
           module.setDisplayToString(leaving);
           delay(1000);
           confirmDone=true;         
         }
       }
       //set back the display
       module.clearDisplay();
       module.setLED(TM1638_COLOR_GREEN, 0);
       module.setLED(TM1638_COLOR_GREEN, 1);
       module.setLED(TM1638_COLOR_RED, 4);
       module.setLED(TM1638_COLOR_GREEN, 7);
       module.setLED(0, 6);
     break;
   } 
 
   module.setDisplayToString(confMenu[confItem-1]);
 
   //avoid button bounce... ¬¬ humans... 
   delay(150);
  }// end RADIO menu 
  
  // servo function
  servoSetup();
  while(!changeMenu) {
    // read keys
    keys = module.getButtons();
    // check if button 5 was pressed
    if( keys == ( button << 4 ) ) {
      break;
    }
    
    switch( keys ) {
       case (button << 0):
         servoPos = 0;
       break;
       case (button << 1):
         servoPos = 90;
       break;
       case (button << 2):
         servoPos = 180;
       break;
       case (button << 6):
         servoPos--;
       break;
       case (button << 7):
         servoPos++;
       break;
     }
 
   delay(50);
   myservo.write(servoPos);
   module.setDisplayToDecNumber(servoPos,0);
  }// end servo function
}          
